/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "softbus_device_report.h"
#include "transmission.h"

#include "session.h"
#include "client_trans_session_service.h"
#include "softbus_common.h"
#include "softbus_bus_center.h"
#include "utils_log.h"

static osThreadId_t g_softbusDeviceTid = NULL;

#define SOFTBUS_POLL_TIMEOUT_TICS    pdMS_TO_TICKS(1000)

static IKHSessionCallback g_sessionCallback = {
    .OnSessionOpened = OnSessionOpened,
    .OnSessionClosed = OnSessionClosed,
    .OnBytesReceived = OnBytesReceived,
    .OnMessageReceived = OnMessageReceived,
    .OnStreamReceived = NULL,
    .OnQosEvent = NULL
};

static void OnSessionOpened(int sessionId, int result) {
    printf("\n>>>OnSessionOpened sessionId = %d, result = %d.\n", sessionId, result);
}

static void OnSessionClosed(int sessionId) {
    printf("\n>>>OnSessionClosed sessionId = %d.\n", sessionId);
}

// static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) {
//     printf("\n>>>OnBytesReceived sessionId = %d, dataLen = %d.\n", sessionId, dataLen);
//     // 处理接收到的字节数据
// }

static void OnBytesReceived(const ReportMessage *msg) {
    if (msg == NULL) {
        printf("OnBytesReceived: msg is NULL\n");
        return;
    }
    printf("\n>>>OnBytesReceived sessionId = %d, dataLen = %d.\n", msg->dataLen);
    // 处理接收到的字节数据
}

static void OnMessageReceived(const ReportMessage *msg) {
    if (msg == NULL) {
        printf("OnMessageReceived: msg is NULL\n");
        return;
    }
    printf("\n>>>OnMessageReceived sessionId = %d, dataLen = %d.\n", msg->dataLen);
    // 处理接收到的消息数据
}

// static void OnMessageReceived(int sessionId, const void *data, unsigned int dataLen) {
//     printf("\n>>>OnMessageReceived sessionId = %d, dataLen = %d.\n", sessionId, dataLen);
//     // 处理接收到的消息数据
// }

static void SoftbusDeviceReportTask(void) {
    bool isGrouped = false;
    int sessionId = -1; // 假设会话ID为-1时表示未建立连接

    while (1) {
        if (!isGrouped) {
            // 组网逻辑
            int ret = BirefCreateSessionServer();
            if (ret == 0) {
                isGrouped = true;
                sessionId = BirefOpenSession("networkId", TYPE_MESSAGE);
            }
        } else {
            // 上报逻辑
            if (IsSessionActive(sessionId)) {
                ReportMessage msg;
                // 假设我们定期生成上报消息
                msg.bundleName = "com.example.test";
                // /msg.SN = "123456789";
                //msg.networkId = 0;
                msg.type = 1;
                msg.port = 8080;
                msg.portOffset = 0;
                msg.dataLen = 100; // 假设数据长度
                // msg.dataLen = strlen((const char *)msg.data);
                msg.data = "Report Data"; // 假设数据内容

                // SendDataToRouter(msg.bundleName, msg.SN, msg.type, msg.port, msg.portOffset, msg.data, msg.dataLen);
                SendDataToRouter(&msg);
            }

            osDelay(SOFTBUS_POLL_TIMEOUT_TICS);
        }
    }
}

int StartSoftbusDeviceReportTask(void) {
    osThreadAttr_t attr;
    attr.name = "SOFTBUS_DEVICE_REPORT_TASK";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 0x2000;
    attr.priority = 25;

    g_softbusDeviceTid = osThreadNew((osThreadFunc_t)SoftbusDeviceReportTask, NULL, &attr);
    if (g_softbusDeviceTid == NULL) {
        printf("Failed to create softbus device report task!\n");
        return -1;
    }
    return 0;
}

void StopSoftbusDeviceReportTask(void) {
    if (NULL == g_softbusDeviceTid) {
        return;
    }

    osThreadTerminate(g_softbusDeviceTid);
    g_softbusDeviceTid = NULL;
}

bool IsSoftbusDeviceAvailable(void) {
    return IsSessionActive(-1); // 简化的可用性检查
}

int SendDataToRouter(const ReportMessage *msg) {
    if (msg == NULL || msg->data == NULL || msg->dataLen <= 0) {
        printf("SendDataToRouter param failed \n");
        LOG_TO_FILE("SendDataToRouter param failed");
        return -1;
    }

    printf("SendDataToRouter-------------------------------------\r\n");
    int sessionId = BirefOpenSession("networkId", msg->type);
    if (sessionId < 0) {
        printf("OpenSession type message failed, sessiond [%d]\n", sessionId);
        LOG_TO_FILE("OpenSession type message failed, sessiond [%d]\n", sessionId);
        return sessionId;
    }
        // 根据type决定发送方式
    int ret = 0;
    if (msg->type == TYPE_BYTES) {
        ret = SendBytes(sessionId, msg->data, msg->dataLen);
    } else if (msg->type == TYPE_MESSAGE) {
        ret = SendMessage(sessionId, msg->data, msg->dataLen);
    } else {
        ret = -1; // 未知类型
    }

    if (ret < 0) {
        printf("Send %s type failed, ret [%d]\n", (msg->type == TYPE_BYTES) ? "Bytes" : "Message", ret);
        LOG_TO_FILE("Send %s type failed, ret [%d]\n", (msg->type == TYPE_BYTES) ? "Bytes" : "Message", ret);
        CloseSession(sessionId);
    }
    return ret;
}

static ISessionListener listener = {
    .OnSessionOpened = OnSessionOpened,
    .OnSessionClosed = OnSessionClosed,
    .OnBytesReceived = OnBytesReceived,
    .OnMessageReceived = OnMessageReceived,
    .OnStreamReceived = NULL,
    .OnQosEvent = NULL
};

void RegisterSessionCallback(IKHSessionCallback *callback)
{
    g_callback = callback;
}